package edu.server.dominio;

import java.util.List;

import org.hibernate.Hibernate;
import org.hibernate.HibernateException;
import org.hibernate.Session;

import edu.server.repositorio.OrdenPedido;
import edu.server.repositorio.RenglonOrdenPedido;
import edu.server.repositorio.RenglonOrdenPedidoId;
import edu.server.util.HibernateUtil;

public class D_OrdenPedido {
	
	public D_OrdenPedido()
	{
		
	}
	
	/**
	 * Método que busca en la base de datos todas las órdenes de pedido que cumplen con los parámentos de entrada.
	 * @param numeroOrden. Número de la orden de pedido. Si vale cero no se filtra por esta propiedad.
	 * @param nombreCliente. Nombre del cliente al cual pertenece la orden de pedido. Si se envía la cadena vacía, se busca por todos los clientes.
	 * @return List<OrdenPedido>. Retorna una lista con las órdenes de pedido que coinciden con los parámentros de entrada.
	 */
	@SuppressWarnings("unchecked")
	public List<OrdenPedido> buscarOrdenPedido(int numeroOrden, String nombreCliente)
	{
		List<OrdenPedido> ordenesPedido;
		
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		
		session.beginTransaction();
		
		String operadorLogico = " WHERE";
		
		//consulta para la búsqueda
		String hql = "FROM OrdenPedido op";
		
		//filtramos por nombre de cliente
		if(!nombreCliente.equals(""))
		{
			hql = hql + operadorLogico + " op.cliente.nombre LIKE '%" + nombreCliente +"%'";
			operadorLogico = " AND";
		}
		
		//si no se envió cero como número de orden, filtramos por el número de la orden de pedido
		if(numeroOrden != 0)
		{
			hql = hql + operadorLogico + " nroOrden = " + numeroOrden;
			operadorLogico = " AND";
		}
		
		hql = hql + operadorLogico + " nroOrden NOT IN ( SELECT op2.nroOrden " +
											"FROM OrdenPedido op2, OrdenFabricacionGeneral ordenFabricacion "+
											"WHERE op2.nroOrden = ordenFabricacion.ordenPedido.nroOrden )";
		
		ordenesPedido = session.createQuery(hql).list();
		
		//inicializamos los datos del cliente para cada orden de pedido
		for(OrdenPedido ordenPedido : ordenesPedido)
			Hibernate.initialize(ordenPedido.getCliente());
		
		session.close();
		
		return ordenesPedido;
	}

	public OrdenPedido buscarOrdenPedido(long numeroOrden)	{
		OrdenPedido ordenPedido;
		
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		
		session.beginTransaction();
		
		//Buscamos la orden por su id.
		String hql = "FROM OrdenPedido WHERE nroOrden = " + numeroOrden;
		
		ordenPedido = (OrdenPedido) session.createQuery(hql).uniqueResult();
		
		//Inicializamos los datos de la orden de pedido.
		Hibernate.initialize(ordenPedido.getCliente());
		
		for (RenglonOrdenPedido renglon: ordenPedido.getRenglonOrdenPedidos()) {
			renglon.getId();
			renglon.getComponentePatron();
			renglon.getEquipoPatron();
		}

		session.close();
		
		return ordenPedido;
	}
	
	/**
	 * Método que busca un renglón de orden de pedido en la base de datos
	 * @param idRenglon. Id del renglón que estamos buscando.
	 * @return RenglonOrdenPedido. Retorna el renglón de orden de pedido que concuerda con el id pasado como parámetro.
	 */
	public RenglonOrdenPedido buscarRenglon(RenglonOrdenPedidoId idRenglon)
	{
		RenglonOrdenPedido renglon;
		
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		
		session.beginTransaction();
		
		renglon = (RenglonOrdenPedido)session.get(RenglonOrdenPedido.class, idRenglon);
					
		session.close();
		
		return renglon;
	}
	
	
	@SuppressWarnings("unchecked")
	public List<RenglonOrdenPedido> buscarRenglones(int numeroOrden)
	{
		List<RenglonOrdenPedido> renglones;
		
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		
		session.beginTransaction();
		
		renglones = session.createQuery("FROM RenglonOrdenPedido r WHERE r.ordenPedido.nroOrden = " + numeroOrden).list();
				
		for(RenglonOrdenPedido renglon : renglones)
		{
			//inicializamos el equipo patrón
			Hibernate.initialize(renglon.getEquipoPatron());
			
			//si el renglón tiene cargado un equipo, inicializamos sus datos
			if(renglon.getEquipoPatron() != null)
			{
				Hibernate.initialize(renglon.getEquipoPatron().getSubclaseEquipoPatron());
				Hibernate.initialize(renglon.getEquipoPatron().getSubclaseEquipoPatron().getClaseEquipoPatron());
				Hibernate.initialize(renglon.getEquipoPatron().getListaDeMateriales());
			}
			
			//caso contrario, inicializamos los datos del componente
			else
			{
				Hibernate.initialize(renglon.getComponentePatron());
				Hibernate.initialize(renglon.getComponentePatron().getSubclaseEquipoPatron());
				Hibernate.initialize(renglon.getComponentePatron().getSubclaseEquipoPatron().getClaseEquipoPatron());
				Hibernate.initialize(renglon.getComponentePatron().getListaDeMateriales());
			}
		}
		
		session.close();
		
		return renglones;
	}

	
	public void registrar(OrdenPedido orden)
	{
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		try
		{
			session.beginTransaction();
			session.saveOrUpdate(orden);
			session.getTransaction().commit();
		}
		
		catch(HibernateException he)
		{
			session.getTransaction().rollback();
			throw he;
		}
	}
}
